# encoding: utf-8
"""
图片hash处理
@author: xiao nian
@contact: xiaonian030@163.com
@date: 2022-09-08
"""

__copyright__ = "Copyright (c) (2022-2022) QF Inc. All Rights Reserved"
__author__ = "Xiao Nian"
__date__ = "2022-09-10:14:13:24"
__version__ = "1.0.0"

import cv2
import numpy as np


def average_hash(img, shape=(8, 8)):
    """
    均值hash算法
    """
    # 缩放
    img_resize = cv2.resize(img, shape)
    # 转换为灰度图
    img_gray = cv2.cvtColor(img_resize, cv2.COLOR_BGR2GRAY)
    hash_str = ''
    # 求平均灰度
    avg = np.mean(img_gray)
    # 灰度大于平均值为1相反为0生成图片的hash值
    for i in range(shape[1]):
        for j in range(shape[0]):
            if img_gray[i, j] > avg:
                hash_str = hash_str + '1'
            else:
                hash_str = hash_str + '0'
    return hash_str


def difference_Hash(img, shape=(10, 10)):
    """
    差值 hash
    """
    # 缩放10*11
    img_resize = cv2.resize(img, (shape[0]+1, shape[1]))
    # 转换灰度图
    img_gray = cv2.cvtColor(img_resize, cv2.COLOR_BGR2GRAY)
    hash_str = ''
    # 每行前一个像素大于后一个像素为1，相反为0，生成哈希
    for i in range(shape[0]):
        for j in range(shape[1]):
            if img_gray[i, j] > img_gray[i, j + 1]:
                hash_str = hash_str + '1'
            else:
                hash_str = hash_str + '0'
    return hash_str


def perception_Hash(img, shape=(32, 32)):
    """
    感知 hash
    """
    img_resize = cv2.resize(img, shape)

    # 转换为灰度图
    img_gray = cv2.cvtColor(img_resize, cv2.COLOR_BGR2GRAY)
    # 将灰度图转为浮点型，再进行dct变换
    dct = cv2.dct(np.float32(img_gray))
    # opencv实现的掩码操作
    dct_roi = dct[0:10, 0:10]

    hash_str = ''
    avreage = np.mean(dct_roi)
    for i in range(dct_roi.shape[0]):
        for j in range(dct_roi.shape[1]):
            if dct_roi[i, j] > avreage:
                hash_str = hash_str + '1'
            else:
                hash_str = hash_str + '0'
    return hash_str


def compare_hash(hash1, hash2, shape=(10, 10)):
    """
    Hash 相似度计算
    """
    n = 0
    # hash长度不同则返回-1代表传参出错
    if len(hash1) != len(hash2):
        return -1
    # 遍历判断
    for i in range(len(hash1)):
        # 相等则n计数+1，n最终为相似度
        if hash1[i] == hash2[i]:
            n = n + 1
    return n / (shape[0] * shape[1])

